package com.zkthink.ceres.finance.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zkthink.base.R;
import com.zkthink.base.request.PageParams;
import com.zkthink.base.service.SuperServiceImpl;
import com.zkthink.ceres.finance.dao.CashOutDetailMapper;
import com.zkthink.ceres.finance.dto.*;
import com.zkthink.ceres.finance.entity.CashOutDetail;
import com.zkthink.ceres.finance.entity.JournalDetail;
import com.zkthink.ceres.finance.enums.AuditStatusEnum;
import com.zkthink.ceres.finance.enums.CashOutStatusEnum;
import com.zkthink.ceres.finance.enums.JournalTypeEnum;
import com.zkthink.ceres.finance.enums.PaymentTypeEnum;
import com.zkthink.ceres.finance.service.CashOutDetailService;

import com.zkthink.ceres.finance.service.JournalDetailService;
import com.zkthink.ceres.finance.vo.CashOutDetailVO;
import com.zkthink.context.BaseContextHandler;
import com.zkthink.database.mybatis.conditions.Wraps;
import com.zkthink.database.mybatis.conditions.query.QueryWrap;
import com.zkthink.dozer.DozerUtils;
import com.zkthink.exception.BizException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 业务实现类
 * 提现明细表
 * </p>
 *
 * @author vivi.huang
 * @date 2020-05-25
 */
@Slf4j
@Service
@AllArgsConstructor
public class CashOutDetailServiceImpl extends SuperServiceImpl<CashOutDetailMapper, CashOutDetail> implements CashOutDetailService {

    private CashOutDetailMapper cashOutDetailMapper;
    private DozerUtils dozerUtils;
    private JournalDetailService journalDetailService;

    @Override
    public R<Boolean> doCashOut(CashOutDetailSaveDTO collectingAccountSaveDTO) {
        CashOutDetail detail = dozerUtils.map(collectingAccountSaveDTO, CashOutDetail.class);
        detail.setApplyTime(LocalDateTime.now());
        detail.setAuditStatus(AuditStatusEnum.WAIT_TO_PROCESS.getCode());
        detail.setCashOutStatus(CashOutStatusEnum.PROCESSING.getCode());

        if (!checkEnoughBalance(detail.getAmount())) {
            throw new BizException("没有足够的提现余额");
        }

        return R.success(this.save(detail));
    }

    private boolean checkEnoughBalance(Long amount) {
        return true;
    }

    @Override
    public R<IPage<CashOutDetailVO>> findCashOutDetailPage(PageParams<CashOutDetailPageDTO> pageParams) {
        IPage<CashOutDetailVO> page = pageParams.getPage();
        queryCashOutDetail(pageParams, page);
        return R.success(page);
    }

    private void queryCashOutDetail(PageParams<CashOutDetailPageDTO> params, IPage<CashOutDetailVO> page) {
        CashOutDetailPageDTO pageDTO = params.getModel();

        Integer total = this.cashOutDetailMapper.getTotalOfCashOutDetailPage(pageDTO.getStartTime(), pageDTO.getEndTime());

        if (total > 0) {
            List<CashOutDetailVO> cashOutDetailList = this.cashOutDetailMapper.findCashOutDetailPage(
                    pageDTO.getStartTime(), pageDTO.getEndTime(), (page.getCurrent() - 1), page.getSize());

            page.setRecords(cashOutDetailList);
            page.setTotal(total);
        }
    }

    @Override
    public R<IPage<CashOutAuditDTO>> findAuditCashOutDetailPage(PageParams<CashOutAuditPageDTO> pageParams) {
        IPage<CashOutAuditDTO> page = pageParams.getPage();
        queryAuditCashOutDetail(pageParams, page);
        return R.success(page);
    }

    @Override
    public R<Boolean> auditCashOut(CashOutAuditDTO cashOutAuditDTO) {
        this.cashOutDetailMapper.updateAuditSuccess(cashOutAuditDTO.getId());

        //添加提现流水
        CashOutDetail cashOutDetail = this.cashOutDetailMapper.getCashOutDetail(cashOutAuditDTO.getId());
        cashOutDetail.setTenantCode(cashOutAuditDTO.getTenant());
        cashOutDetail.setAuditTime(LocalDateTime.now());
        saveCashOutJournal(cashOutDetail);

        return R.success(true);
    }

    private void saveCashOutJournal(CashOutDetail cashOutDetail) {
        JournalDetailSaveDTO dto = new JournalDetailSaveDTO();
        dto.setPaymentType(PaymentTypeEnum.PAY_OUT.getCode());
        dto.setAmount(cashOutDetail.getAmount());
        dto.setEntryTime(LocalDateTime.now());
        dto.setJournalType(JournalTypeEnum.CASH_OUT.getCode());
        dto.setTenantCode(cashOutDetail.getTenantCode());
        journalDetailService.saveJournalDetail(dto);
    }

    @Override
    public R<CashOutAuditDTO> getCashOutAudit(Long id) {
        return R.success(this.cashOutDetailMapper.getCashOutAudit(id));
    }

    private void queryAuditCashOutDetail(PageParams<CashOutAuditPageDTO> pageParams, IPage<CashOutAuditDTO> page) {
        CashOutAuditPageDTO pageDTO = pageParams.getModel();

        Integer total = this.cashOutDetailMapper.getTotalOfAuditCashOutDetailPage(pageDTO.getStoreName(),
                pageDTO.getTenant(), pageDTO.getApplyTimeString(), pageDTO.getAuditStatus());

        if (total > 0) {
            List<CashOutAuditDTO> cashOutAuditDTOList = this.cashOutDetailMapper.findAuditCashOutDetailPage(
                    pageDTO.getStoreName(), pageDTO.getTenant(), pageDTO.getApplyTimeString(),
                    pageDTO.getAuditStatus(), (page.getCurrent() - 1), page.getSize());

            page.setTotal(total);
            page.setRecords(cashOutAuditDTOList);
        }
    }


}
